#ifndef __M_FMT_H__
#define __M_FMT_H__


#include <string>
#include <assert.h>
#include <time.h>
#include <unordered_map>
#include <sstream>
#include "message.hpp"
#include "level.hpp"


/*
为什么FormatItem类和Formatter类的类成员没有LogMsg，而是在每个函数中传参LogMsg
因为类成员中有LogMsg，意味着创建一个类对象，这个对象只能为这一条LogMsg对应的日志信息服务
而在函数传参中传入LogMsg，创建一个类对象就可以为任意的LogMsg对应的日志信息服务
*/
namespace MyLog
{
    //抽象格式化子项基类
    class FormatItem
    {
    public:
        using ptr = std::shared_ptr<FormatItem>;
        virtual ~FormatItem() {}
        virtual void format(std::ostream& os, const LogMsg& msg) = 0;
    };

    //日志时间
    class DateFormatItem : public FormatItem
    {
    public:
        DateFormatItem(const std::string& dateFmt = "%H:%M:%S")
            :_dateFmt(dateFmt)
        {}

        // virtual void format(std::ostream& os, LogMsg& msg) override
        // {
        //     struct tm* tmp;
        //     tmp = localtime(&(msg._time));
        //     char buffer[32];
        //     if(strftime(buffer, sizeof(buffer), _dateFmt.c_str(), tmp) == 0)
        //         assert(false);
        //     os << buffer;
        // }
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << Time::FormatTime(msg._time, _dateFmt);
        }
        
    private:
        std::string _dateFmt;
    };

    //日志等级
    class LevelFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << LogLevel::ToString(msg._level);
        }
    };

    //文件名
    class FileFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << msg._fileName;
        }
    };

    //行号
    class LineFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            // os << std::to_string(msg._fileLine);
            os << msg._fileLine;
        }
    };

    //线程id
    class IdFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << msg._tid;
        }
    };

    //日志器名称
    class LoggerFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << msg._logger;
        }
    };

    //日志主体消息
    class PayloadFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << msg._payload;
        }
    };

    //换行
    class NewlineFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << "\n";
        }
    };

    //制表符
    class TabFormatItem : public FormatItem
    {
    public:
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << "\t";
        }
    };
    
    //其他字符
    class OtherFormatItem : public FormatItem
    {
    public:
        OtherFormatItem(const std::string& content)
            :_content(content)
        {}
        virtual void format(std::ostream& os, const LogMsg& msg) override
        {
            os << _content;
        }
    private:
        std::string _content;
    };

   
    class Formatter
    {
        /*
            %D 日期
            %p 日志级别
            %f 文件名
            %l 行号
            %t 线程id
            %c 日志器名称
            %g 日志消息
            %n 换行
            %T 制表符
        */
    public:
        using ptr = std::shared_ptr<Formatter>;

        Formatter(const std::string& pattern = "[%D{%Y.%m.%d %H:%M:%S}][%t][%c][%f:%l][%p]<%g>%n")
            :_pattern(pattern)
        {
             if (!parsePattern()) {
                // 解析失败使用默认pattern
                _pattern = "[%D{%Y.%m.%d %H:%M:%S}][%t][%c][%f:%l][%p]<%g>%n";
                parsePattern();
            }
        }

        //对msg进行格式化
        void format(std::ostream& os, const LogMsg& msg)
        {
            // _items.clear();
            // if(!parsePattern())
            //     return;
            // assert(!_items.empty());
            // for(int i = 0; i < _items.size(); ++i)
            // {
            //     assert(i < _items.size());
            //     _items[i]->format(os, msg);
            // }

            for(auto i : _items)
            {
                i->format(os, msg);
            }
        }

        std::string format(const LogMsg& msg)
        {
            //std::ostream是抽象类，不能实例化
            // _items.clear();
            std::stringstream ss;
            format(ss, msg);
            return ss.str();
        }



        // 对格式化规则字符串进行解析
        // bool parsePattern()
        // {
        //     // "[%D{%Y.%m.%d %H:%M:%S}][%t][%c][%f:%l][%p]<%g>%n"

        //     size_t size = _pattern.size();
        //     size_t index = 0;
        //     while(index < size)
        //     {
        //         // std::cout << index << std::endl;
        //         if(_pattern[index] == '%')
        //         {
        //             //单独一个‘%’在最后
        //             if(index + 1 >= size)
        //             {
        //                 std::cout << "% 匹配失败" << std::endl;
        //                 return false;
        //             }
                        
        //             //如果是日期，要处理子串
        //             if(_pattern[index + 1] == 'D')
        //             {
        //                 //如果有指定日期格式
        //                 if(index + 2 < size && _pattern[index + 2] == '{')
        //                 {
        //                     index += 3;
        //                     size_t pos = index;
        //                     while(pos < size && _pattern[pos] != '}')
        //                         ++pos;

        //                     //无 '}'   
        //                     if(pos >= size)
        //                     {
        //                         std::cout << "子规则{}匹配失败" << std::endl;
        //                         return false;
        //                     }
                                
        //                     std::string dateFmt = _pattern.substr(index, pos - index);
        //                     _items.emplace_back(createItem('D', dateFmt));
        //                     index = pos + 1;
        //                 }
        //                 //如果没有，采用默认的
        //                 else
        //                 {
        //                     std::string dateFmt = "%Y.%m.%d %H:%M:%S";
        //                     _items.emplace_back(createItem(_pattern[index + 1], dateFmt));
        //                     index += 2;
        //                 }
        //             }
        //             //‘%’字面量
        //             else if(_pattern[index + 1] == '%')
        //             {
        //                 _items.emplace_back(createItem(' ', "%"));
        //                 index += 2;
        //             }
        //             //其他情况
        //             else
        //             {
        //                 FormatItem::ptr p = createItem(_pattern[++index], "");
        //                 if(p == nullptr)
        //                 {
        //                     std::cout << "未定义的格式化字符: " << _pattern[index] << std::endl;
        //                     assert(false);
        //                 }
        //                 _items.emplace_back(p);
        //                 ++index;
        //             }
        //         }
        //         else
        //             _items.emplace_back(createItem(' ', std::string(1, _pattern[index++])));
        //     }
        //     return true;
        // }
        bool parsePattern()
        {
            _items.clear();
            _items.reserve(_pattern.size() / 2 + 10); // 预分配减少重新分配
            
            size_t size = _pattern.size();
            size_t index = 0;
            
            // 先收集普通文本段
            std::string current_text;
            
            while (index < size)
            {
                // 处理普通文本（非%开头）
                if (_pattern[index] != '%')
                {
                    size_t text_start = index;
                    while (index < size && _pattern[index] != '%')
                    {
                        ++index;
                    }
                    
                    // 批量添加普通文本
                    if (index > text_start)
                    {
                        std::string text = _pattern.substr(text_start, index - text_start);
                        _items.emplace_back(createItem(' ', text));
                    }
                    continue;
                }
                
                // 处理%格式符
                if (index + 1 >= size)
                {
                    std::cerr << "% 匹配失败" << std::endl;
                    return false;
                }
                
                char format_char = _pattern[index + 1];
                
                // 处理%%转义
                if (format_char == '%')
                {
                    _items.emplace_back(createItem(' ', "%"));
                    index += 2;
                    continue;
                }
                
                // 处理%D{...}日期格式
                if (format_char == 'D' && index + 2 < size && _pattern[index + 2] == '{')
                {
                    index += 3; // 跳过%D{
                    size_t fmt_start = index;
                    
                    // 查找闭合的}
                    while (index < size && _pattern[index] != '}')
                    {
                        ++index;
                    }
                    
                    if (index >= size)
                    {
                        std::cerr << "子规则{}匹配失败" << std::endl;
                        return false;
                    }
                    
                    std::string date_fmt = _pattern.substr(fmt_start, index - fmt_start);
                    _items.emplace_back(createItem('D', date_fmt));
                    index += 1; // 跳过}
                }
                else
                {
                    // 处理其他简单格式符
                    FormatItem::ptr item = createItem(format_char, "");
                    if (!item)
                    {
                        std::cerr << "未定义的格式化字符: %" << format_char << std::endl;
                        return false;
                    }
                    _items.emplace_back(item);
                    index += 2;
                }
            }
            
            return true;
        }
       
    private:
        //根据不同的格式化字符串创建不同的格式化子项对象
        // FormatItem::ptr createItem(char key, const std::string& content)
        // {
        //     if(key == 'D')
        //         return std::make_shared<DateFormatItem>(content);
        //     else if(key == 'p')
        //         return std::make_shared<LevelFormatItem>();
        //     else if(key == 'f')
        //         return std::make_shared<FileFormatItem>();
        //     else if(key == 'l')
        //         return std::make_shared<LineFormatItem>();
        //     else if(key == 't')
        //         return std::make_shared<IdFormatItem>();
        //     else if(key == 'c')
        //         return std::make_shared<LoggerFormatItem>();
        //     else if(key == 'g')
        //         return std::make_shared<PayloadFormatItem>();
        //     else if(key == 'n')
        //         return std::make_shared<NewlineFormatItem>();
        //     else if(key == 'T')
        //         return std::make_shared<TabFormatItem>();
        //     else if(key == ' ')
        //         return std::make_shared<OtherFormatItem>(content);
        //     else
        //         return nullptr;
        // }

        FormatItem::ptr createItem(char key, const std::string& content)
        {
            // 使用static缓存无状态对象
            static std::unordered_map<char, FormatItem::ptr> cached_items;
            
            // 无状态对象可以复用
            if (key != 'D' && key != ' ') // 除了需要参数的项
            {
                auto it = cached_items.find(key);
                if (it != cached_items.end())
                {
                    return it->second;
                }
                
                FormatItem::ptr item;
                switch (key)
                {
                    case 'p': item = std::make_shared<LevelFormatItem>(); break;
                    case 'f': item = std::make_shared<FileFormatItem>(); break;
                    case 'l': item = std::make_shared<LineFormatItem>(); break;
                    case 't': item = std::make_shared<IdFormatItem>(); break;
                    case 'c': item = std::make_shared<LoggerFormatItem>(); break;
                    case 'g': item = std::make_shared<PayloadFormatItem>(); break;
                    case 'n': item = std::make_shared<NewlineFormatItem>(); break;
                    case 'T': item = std::make_shared<TabFormatItem>(); break;
                    default: return nullptr;
                }
                
                cached_items[key] = item;
                return item;
            }
            
            // 需要参数的项
            switch (key)
            {
                case 'D': return std::make_shared<DateFormatItem>(content);
                case ' ': return std::make_shared<OtherFormatItem>(content);
                default: return nullptr;
            }
        }
    private:
        std::string _pattern; //格式化规则字符串
        std::vector<FormatItem::ptr> _items;
    };
}

#endif
